#include "CharacterEditForm.h"
#include "ui_CharacterEditForm.h"



#include "DataViewDelegate.h"



#include <CharacterItem.h>
#include <CampaignItem.h>
#include <FileHandler.h>



CharacterEditFormBase::CharacterEditFormBase(QWidget *parent) :
    QWidget(parent),
    ui(new Ui::CharacterEditForm)
{
    ui->setupUi(this);
    ui->comboBoxCampaign->blockSignals(true);
    ui->comboBoxCampaign->addItem(ui->actionOpen_Campaign->text());
    ui->comboBoxCampaign->blockSignals(false);

    // Item view initializations
    m_characterModel = new D20BaseModel(this);
    ui->treeViewCharacterData->setModel(m_characterModel);
    ui->treeViewCharacterData->setItemDelegate(new DataViewDelegate(this));
    ui->treeViewCharacterData->header()->setResizeMode(QHeaderView::ResizeToContents);

    m_campaignModel = new ItemModel(this);
    ui->treeViewCampaignData->setModel(m_campaignModel);
    ui->treeViewCampaignData->setItemDelegate(new DataViewDelegate(this));
    ui->treeViewCampaignData->header()->setResizeMode(QHeaderView::ResizeToContents);


    ui->treeViewSkills->header()->setResizeMode(QHeaderView::ResizeToContents);


    // Actions
    addAction(ui->actionChange_View);
    addAction(ui->actionAdd_Group);
    addAction(ui->actionAdd_Item);
    addAction(ui->actionDelete);
    addAction(ui->actionAdd_Reference);
    addAction(ui->actionOpen_Campaign);


    // Other initializations
    on_pushButtonAbilities_clicked();
    on_pushButtonDescription_clicked();
    on_actionChange_View_triggered();

}



CharacterEditFormBase::~CharacterEditFormBase()
{
    delete ui;
}



void CharacterEditFormBase::updateData()
{
    on_lineEditName_editingFinished();
}



QString CharacterEditFormBase::message() const
{
    if (!root()) return tr("Invalid Character!");

    QString campaignMessage = QString("No campaign!");

    CampaignItem* campaignRoot = dynamic_cast<CampaignItem*> (m_campaignModel->rootItem());
    if (campaignRoot) campaignMessage = QString("%1 (%2)").arg(campaignRoot->name()).arg(campaignRoot->filePath());

    return QString("%1 - %2, %3: %4").arg(root()->name()).arg(root()->filePath()).arg(tr("in campaign")).arg(campaignMessage);
}



CharacterItem* CharacterEditFormBase::character() const
{
    return qobject_cast<CharacterItem*>(root());
}



void CharacterEditFormBase::initialize()
{
    CharacterItem* characterRoot = character();
    if (!characterRoot) return;


    m_characterModel->setRootItem(characterRoot);
    ui->lineEditName->setText(characterRoot->name());

    openCampaign(characterRoot->campaignFile());

    connect(FileHandler::instance(), SIGNAL(sigItemOpened()), this, SLOT(onUpdateCampaigns()));

}



void CharacterEditFormBase::openCampaign(const QString& campaign_file)
{
    if (campaign_file.isEmpty()) return;

//    CharacterItem* characterRoot = dynamic_cast<CharacterItem*>(root());
//    if (!characterRoot)
//    {
//        return;
//    }

    CampaignItem* campaignRoot = dynamic_cast<CampaignItem*>(FileHandler::open(campaign_file));
    if (!campaignRoot)
    {
        return;
    }


    m_campaignModel->setRootItem(campaignRoot);

    ui->comboBoxCampaign->blockSignals(true);

    int index = ui->comboBoxCampaign->findData(campaignRoot->filePath());

    if (index < 0)
    {
        index = ui->comboBoxCampaign->count()-1;
        ui->comboBoxCampaign->insertItem(index, campaignRoot->name(), campaignRoot->filePath());
    }

    ui->comboBoxCampaign->setCurrentIndex(index);
    ui->comboBoxCampaign->blockSignals(false);

    validate();

    root()->setData(CharacterItem::CampaignData, campaign_file);
}


void CharacterEditFormBase::validate()
{
#if 0
    CharacterItem* characterRoot = rootItem<CharacterItem*>();
    if (characterRoot->campaignFile().isEmpty())
    {
        QModelIndex campaignMatchStart = m_campaignModel->index(0, AbstractItem::IdData, QModelIndex());
        QModelIndexList foundIndexes = m_campaignModel->match(campaignMatchStart,
                                                              Qt::EditRole,
                                                              "Class Template",
                                                              1,
                                                              Qt::MatchEndsWith | Qt::MatchRecursive);

        if (foundIndexes.isEmpty())
        {
            QMessageBox::warning(this, tr("Invalid Campaign!"), tr("Campaign is invalid: Class Template does not exist!"));
            return;
        }

        QModelIndex classTemplateIndex = foundIndexes.first();


        while (classTemplateIndex)
    }


#endif
}



void CharacterEditFormBase::onUpdateCampaigns()
{
    ui->comboBoxCampaign->blockSignals(true);
    foreach (ItemRoot* rootItem,FileHandler::openItems())
    {
        if (!dynamic_cast<CampaignItem*>(rootItem)) continue;

        if (ui->comboBoxCampaign->findData(rootItem->filePath()) >= 0) continue;

        ui->comboBoxCampaign->insertItem(
                ui->comboBoxCampaign->count()-1,
                rootItem->name(),
                rootItem->filePath());
    }
    ui->comboBoxCampaign->blockSignals(false);
}



void CharacterEditFormBase::on_pushButtonAbilities_clicked()
{
    ui->plainTextEditAbilities->setVisible(ui->pushButtonAbilities->isChecked());
}



void CharacterEditFormBase::on_pushButtonDescription_clicked()
{
    ui->plainTextEditDescription->setVisible(ui->pushButtonDescription->isChecked());
}



void CharacterEditFormBase::on_actionChange_View_triggered()
{
    if (ui->stackedWidget->currentWidget() == ui->pageData) ui->stackedWidget->setCurrentWidget(ui->pageEdit);
    else ui->stackedWidget->setCurrentWidget(ui->pageData);

    ui->actionAdd_Group->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionAdd_Item->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionDelete->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
    ui->actionAdd_Reference->setEnabled(ui->stackedWidget->currentWidget() == ui->pageData);
}



void CharacterEditFormBase::on_lineEditName_editingFinished()
{
    ItemRoot* rootItem = root();
    if (!rootItem) return;

    rootItem->setData(AbstractItem::NameData, ui->lineEditName->text());
}


void CharacterEditFormBase::on_actionAdd_Group_triggered()
{
    QAbstractItemModel* model = ui->treeViewCharacterData->model();
    if (!model) return;

    model->insertRows(model->rowCount(QModelIndex()), 1, QModelIndex());
    ui->treeViewCharacterData->setCurrentIndex(model->index(model->rowCount(QModelIndex())-1,0,QModelIndex()));
}



void CharacterEditFormBase::on_actionAdd_Item_triggered()
{
    QAbstractItemModel* model = ui->treeViewCharacterData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewCharacterData->currentIndex();
    if (!index.isValid()) return;

    QVariant category = index.sibling(index.row(), AbstractItem::CategoryData).data(Qt::EditRole);
    if (!category.isValid()) return;

    QModelIndex parent;
    switch (category.toInt())
    {
    case ItemCategory_Root: return;
    case ItemCategory_Group: { parent = index; break; }
    case ItemCategory_Item:  { parent = index.parent(); break; }
    case ItemCategory_Reference: { parent = index.parent().parent(); break; }
    default: return;
    }

    model->insertRows(model->rowCount(parent), 1, parent);
    ui->treeViewCharacterData->setCurrentIndex(model->index(model->rowCount(parent)-1,0,parent));
}



void CharacterEditFormBase::on_actionDelete_triggered()
{
    QAbstractItemModel* model = ui->treeViewCharacterData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewCharacterData->currentIndex();
    if (!index.isValid()) return;

    model->removeRows(index.row(), 1, index.parent());
}



void CharacterEditFormBase::on_actionAdd_Reference_triggered()
{
    QAbstractItemModel* model = ui->treeViewCharacterData->model();
    if (!model) return;

    QModelIndex index = ui->treeViewCharacterData->currentIndex();
    if (!index.isValid()) return;

    QVariant category = index.sibling(index.row(), AbstractItem::CategoryData).data(Qt::EditRole);
    if (!category.isValid()) return;

    QModelIndex parent;
    switch (category.toInt())
    {
    case ItemCategory_Item:         { parent = index; break; }
    case ItemCategory_Reference:    { parent = index.parent(); break; }

    case ItemCategory_Root:         return;
    case ItemCategory_Group:        return;
    default: return;
    }

    model->insertRows(model->rowCount(parent), 1, parent);
    ui->treeViewCharacterData->setCurrentIndex(model->index(model->rowCount(parent)-1,0,parent));
}


void CharacterEditFormBase::on_comboBoxCampaign_currentIndexChanged(int index)
{
    QString file_path = ui->comboBoxCampaign->itemData(index).toString();
    if (file_path.isEmpty())
    {
        on_actionOpen_Campaign_triggered();
        return;
    }

    openCampaign(file_path);
}

void CharacterEditFormBase::on_actionOpen_Campaign_triggered()
{
    QString file_path = QFileDialog::getOpenFileName(0, ui->actionOpen_Campaign->text(), QDir::currentPath(), tr("Xml File (*.xml)"));
    if (!file_path.isEmpty())
    {
        openCampaign(file_path);
        return;
    }

    //... set previous campaign selected, if any...
}
